#include <linux/sched/task_types.h>
#include <linux/sched/task.h>
#include <linux/thread_info.h>
#include <asm/processor.h>
#include <linux/sched/task_stack.h>
#include <asm/ptrace.h>
#include <linux/preempt.h>

extern void ret_from_fork(void);

int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
    struct pt_regs *childregs = task_pt_regs(p);
    struct thread_info *thread = task_thread_info(p);

    if (args->fn)
    {
        thread->s[0] = (unsigned long)args->fn;
        thread->s[1] = (unsigned long)args->fn_arg;
    }
    else
    {
    }

    thread->ra = (unsigned long)ret_from_fork;
    thread->sp = (unsigned long)childregs; /* kernel sp */

    return 0;
}

void init_thread_info(struct task_struct *p)
{
    struct thread_info *ti = task_thread_info(p);

    ti->flags = 0;
    ti->preempt.val[0] = INIT_PREEMPT_COUNT;
}
